﻿using System;
using System.Collections.Generic;
using System.Configuration.Provider;
using System.Web.Configuration;

namespace AnOtherBlog.Core.Providers
{
	/// <summary>
	/// Clase que facilita el acceso a los datos de acuerdo al proveedor
	/// de datos que se ha establecido en el web.config
	/// </summary>
	public static class DataAccess
	{

		#region Provider

		private static DataProvider _Provider;
		/// <summary>
		/// Acceso al proveedor de datos actual
		/// </summary>
		public static DataProvider Provider
		{
			get
			{
				LoadProviders();
				return _Provider;
			}
		}

		private static DataProviderCollection _ProviderCollection;
		/// <summary>
		/// Acceso a la colección de proveedores registrados en el web.config
		/// </summary>
		public static DataProviderCollection ProviderCollection
		{
			get
			{
				LoadProviders();
				return _ProviderCollection;
			}
		}

		private static object _lock = new object();
		/// <summary>
		/// Carga los proveedores desde el web.config
		/// </summary>
		private static void LoadProviders()
		{
			// Verificar que no se ha cargado el proveedor
			if (_Provider == null)
			{
				lock (_lock)
				{
					// Esto hay que chequearlo dos veces porque puede actualizarse entre la verificación de null y el lock
					if (_Provider == null)
					{
						// Obtener una referencia a la sección donde se declaran los proveedores
						DataProviderSection providerSection = (DataProviderSection)WebConfigurationManager.GetSection("AnOtherBlog/dataProvider");
						// Cargar los proveedores registrados
						_ProviderCollection = new DataProviderCollection();
						ProvidersHelper.InstantiateProviders(providerSection.Providers, _ProviderCollection, typeof(DataProvider));
						_Provider = _ProviderCollection[providerSection.DefaultProvider];
						if (_Provider == null)
						{
							throw new ProviderException("No se puede cargar el proveedor por defecto en DataProvider");
						}
					}
				}
			}
		}

		#endregion

		#region Blog Data Access
		///// <summary>
		///// Obtiene la configuración de un blog de acuerdo a su id
		///// </summary>
		///// <param name="id">Identificador del blog</param>
		///// <returns>Blog</returns>
		//public static Blog BlogSelect(int id)
		//{
		//  return Provider.BlogSelect(id);
		//}

		/// <summary>
		/// Obtiene la configuración de un blog de acuerdo a su dominio
		/// </summary>
		/// <param name="domain">Dominio del blog</param>
		/// <returns>Blog</returns>
		public static Blog BlogSelect(string domain)
		{
			return Provider.BlogSelect(domain);
		}

		/// <summary>
		/// Inserta la configuración de un blog
		/// </summary>
		/// <param name="blog">Blog a insertar</param>
		public static void BlogInsert(Blog blog)
		{
			Provider.BlogInsert(blog);
		}

		/// <summary>
		/// Modifica la configuración de un blog
		/// </summary>
		/// <param name="blog">Blog a modificar</param>
		public static void BlogUpdate(Blog blog)
		{
			Provider.BlogUpdate(blog);
		}

		#endregion

		#region Category Data Access
		/// <summary>
		/// Obtiene una categoría
		/// </summary>
		/// <param name="id">Identificador de la categoría</param>
		/// <returns>Categoria</returns>
		public static Category CategorySelect(Guid id)
		{
			return Provider.CategorySelect(id);
		}

		/// <summary>
		/// Inserta una categoría
		/// </summary>
		/// <param name="category">Categoría a insertar</param>
		public static void CategoryInsert(Category category)
		{
			Provider.CategoryInsert(category);
		}

		/// <summary>
		/// Modifica una categoría
		/// </summary>
		/// <param name="category">Categoría a modificar</param>
		public static void CategoryUpdate(Category category)
		{
			Provider.CategoryUpdate(category);
		}

		/// <summary>
		/// Suprime una categoría
		/// </summary>
		/// <param name="category">Categoría a suprimir</param>
		public static void CategoryDelete(Category category)
		{
			Provider.CategoryDelete(category);
		}

		/// <summary>
		/// Obtiene la lista de todas las categorías
		/// </summary>
		/// <returns>Colección de categorías</returns>
		public static List<Category> CategoryList()
		{
			return Provider.CategoryList();
		}

		#endregion

		#region Page Data Access
		/// <summary>
		/// Obtiene una página
		/// </summary>
		/// <param name="id">Identificador de la página</param>
		/// <returns>Página</returns>
		public static Page PageSelect(Guid id)
		{
			return Provider.PageSelect(id);
		}

		/// <summary>
		/// Inserta una página
		/// </summary>
		/// <param name="page">Página a insertar</param>
		public static void PageInsert(Page page)
		{
			Provider.PageInsert(page);
		}

		/// <summary>
		/// Modifica una página
		/// </summary>
		/// <param name="page">Página a modificar</param>
		public static void PageUpdate(Page page)
		{
			Provider.PageUpdate(page);
		}

		/// <summary>
		/// Suprime una página
		/// </summary>
		/// <param name="page">Página a suprimir</param>
		public static void PageDelete(Page page)
		{
			Provider.PageDelete(page);
		}

		/// <summary>
		/// Obtiene la lista de todas las páginas
		/// </summary>
		/// <returns>Colección de páginas</returns>
		public static List<Page> PageList()
		{
			return Provider.PageList();
		}
		/// <summary>
		/// Obtiene la lista de todas las páginas en modo proxy
		/// </summary>
		/// <param name="isProxy">Modo de carga true=lectura reducida</param>
		/// <returns>Colección de páginas</returns>
		public static List<Page> PageList(bool isProxy)
		{
			return Provider.PageList(isProxy);
		}

		#endregion

		#region Post Data Access
		/// <summary>
		/// Obtiene una publicación
		/// </summary>
		/// <param name="id">Identificador de la publicación</param>
		/// <returns>Post</returns>
		public static Post PostSelect(Guid id)
		{
			return Provider.PostSelect(id);
		}

		/// <summary>
		/// Inserta una publicación
		/// </summary>
		/// <param name="post">Publicación a insertar</param>
		public static void PostInsert(Post post)
		{
			Provider.PostInsert(post);
		}

		/// <summary>
		/// Modifica una publicacíon
		/// </summary>
		/// <param name="post">Publicación a modificar</param>
		public static void PostUpdate(Post post)
		{
			Provider.PostUpdate(post);
		}

		/// <summary>
		/// Suprime una publicacíon
		/// </summary>
		/// <param name="post">Publicacíon a suprimir</param>
		public static void PostDelete(Post post)
		{
			Provider.PostDelete(post);
		}

		/// <summary>
		/// Obtiene la lista de todas las publicaciones
		/// </summary>
		/// <returns>Colección de publicaciones</returns>
		public static List<Post> PostList()
		{
			return Provider.PostList();
		}

		/// <summary>
		/// Obtiene la lista de todas las publicaciones
		/// </summary>
		/// <param name="isProxy">Modo de carga true=lectura reducida</param>
		/// <returns>Colección de publicaciones</returns>
		public static List<Post> PostList(bool isProxy)
		{
			return Provider.PostList(isProxy);
		}

		#endregion

		#region Comment Data Access
		/// <summary>
		/// Obtiene un comentario
		/// </summary>
		/// <param name="id">Identificador del comentario </param>
		/// <returns>Comment</returns>
		public static Comment CommentSelect(Guid id)
		{
			return Provider.CommentSelect(id);
		}

		/// <summary>
		/// Inserta un comentario
		/// </summary>
		/// <param name="comment">Comentario a insertar</param>
		public static void CommentInsert(Comment comment)
		{
			Provider.CommentInsert(comment);
		}

		/// <summary>
		/// Modifica un comentario
		/// </summary>
		/// <param name="comment">Comentario a modificar</param>
		public static void CommentUpdate(Comment comment)
		{
			Provider.CommentUpdate(comment);
		}

		/// <summary>
		/// Suprime un comentario
		/// </summary>
		/// <param name="comment">comentario a suprimir</param>
		public static void CommentDelete(Comment comment)
		{
			Provider.CommentDelete(comment);
		}

		///// <summary>
		///// Obtiene la lista de todas las publicaciones
		///// </summary>
		///// <returns>Colección de publicaciones</returns>
		//public static List<Post> PostList()
		//{
		//  return Provider.PostList();
		//}

		///// <summary>
		///// Obtiene la lista de todas las publicaciones
		///// </summary>
		///// <param name="isProxy">Modo de carga true=lectura reducida</param>
		///// <returns>Colección de publicaciones</returns>
		//public static List<Post> PostList(bool isProxy)
		//{
		//  return Provider.PostList(isProxy);
		//}

		#endregion

	}
}
